package com.uft.was.connector;

import java.io.Serializable;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;

import javax.management.Notification;
import javax.management.NotificationFilterSupport;
import javax.management.NotificationListener;
import javax.management.ObjectName;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;

import com.ibm.websphere.management.AdminClient;
import com.ibm.websphere.management.NotificationConstants;
import com.uft.model.dao.ServerDAO;
import com.uft.model.entity.Server;
import com.uft.model.entity.ServerRuntime;
import com.uft.service.ApplicationContextUtils;

public class WasManagementListener implements NotificationListener,Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private ObjectName query=null;
	private NotificationFilterSupport filter=null;
	private boolean enableNotification=false;
	private  static Logger  logger = Logger.getLogger(WasManagementListener.class);
	public void handleNotification(Notification notification, Object handback) {
		// TODO Auto-generated method stub
		logger.debug("Notification: "+notification.getMessage());
		HashMap<String,String> notyHash=new HashMap<String,String>();
		ApplicationContext appCtx = ApplicationContextUtils.getApplicationContext();
		//ServerRuntime serverRuntime=appCtx.getBean(ServerRuntime.class);
		ServerDAO serverDAO=appCtx.getBean(ServerDAO.class);
		String type=notification.getType().replaceAll("websphere.process.", "").toUpperCase();
		notyHash.put("type", type);
		logger.debug("Type: "+type);
		Calendar notificationTime=Calendar.getInstance();
		notificationTime.setTimeInMillis(notification.getTimeStamp());
		logger.debug("notificationTime: "+notificationTime.getTime());
		notyHash.put("notificationTime", notificationTime.getTime().toString());
		
		String source=notification.getSource().toString();
		source=source.replaceAll("\\{","");
		source=source.replaceAll("\\}", "");
		logger.debug("source: "+source);
		String[] sourceArray=source.split(",");
		for(String st:sourceArray){
			String[] stArry=st.split("=");
			if(stArry.length > 1){
				if(stArry[0].trim().equalsIgnoreCase("cell")){
					notyHash.put("cell", stArry[1].trim());
					logger.debug("cell: "+stArry[1].trim());
				}
				if(stArry[0].trim().equalsIgnoreCase("node")){
					notyHash.put("node", stArry[1].trim());
					logger.debug("node: "+stArry[1].trim());
				}
			}
		}
		String userData=notification.getUserData().toString();
		logger.debug("userData: "+userData);
		userData=userData.replaceAll("\\{","");
		userData=userData.replaceAll("\\}", "");
		logger.debug("userData: "+userData);
		String[] stringArray=userData.split(",");
		
		for(String st:stringArray){
			
			String[] stArry=st.split("=");
			if(stArry.length > 1){
				if(stArry[0].trim().equalsIgnoreCase("processName")){
					logger.debug("server: "+stArry[1].trim());
					notyHash.put("server", stArry[1].trim());
					break;
				}
				
			}
			
		}
		if(!notyHash.isEmpty()){
			String nodeName=notyHash.get("node");
			String serverName=notyHash.get("server");
			List<Server> servers=serverDAO.getServerByNameNode(serverName, nodeName, 0, 20);
			for(Server server: servers){
				ServerRuntime serverRuntime=server.getServerRuntime();
				serverRuntime.setStatus(notyHash.get("type"));
				serverDAO.updateServerRuntime(serverRuntime);
			}
		}
	}
	public void registerStatusNotificationListener(AdminClient ac){
		try
        {
        	query = new ObjectName("WebSphere:*");
        	filter = new NotificationFilterSupport();
            filter.enableType(NotificationConstants.TYPE_PROCESS_STOPPING);
            filter.enableType(NotificationConstants.TYPE_PROCESS_STOPPED);
            filter.enableType(NotificationConstants.TYPE_PROCESS_STARTING);
            filter.enableType(NotificationConstants.TYPE_PROCESS_RUNNING);
            ac.addNotificationListenerExtended(query, this, filter, null);
            enableNotification=true;
            logger.info("Registered for Status event notifications");
        }
        catch (Exception e)
        {
        	logger.error(e);
            e.printStackTrace();
            System.exit(-1);
        }
	}
	public void removeNotificationListener(AdminClient ac){
		try
        {
			logger.info("Admin Connection Domain : "+ac.getDomainName());
		 if(enableNotification){
			 ac.removeNotificationListenerExtended(query, this);
			 logger.info("Remove Notification listener");
			 enableNotification=false;
		 }
		 
        }
	 catch (Exception e)
        {
		 	logger.error(e);
            e.printStackTrace();
           
        }
	}
	

}
